<template>
    <section>
        <div class="form">
            <el-input tabindex="0" :prefix-icon="Search" size="large" ref="search-input" v-model="search"
                placeholder="名称、路径、描述" @input="searchChange" clearable @keyup.enter="enterHandle" />
        </div>
        <div>
            <el-scrollbar height="145px" class="result" ref="result-ref" tabindex="1" always>
                <div class="item" v-for="(res, index) in searchResult" :key="res.id" @mouseover="focusIndex = index + 1"
                    :class="{ active: index + 1 === focusIndex }" @keyup.enter="openInVsCode(res.path)"
                    :tabindex="index + 1" @click="openInVsCode(res.path)">
                    <span class="name" :title="res.name">{{ res.name }}</span>
                    <span class="path" :title="res.path">{{ res.path }}</span>
                    <span class="description" :title="res.description">{{ res.description }}</span>
                    <div class="operate">
                        <el-link type="primary" :underline="false" @click.stop="openInFinder(res.path)" title="文件夹中打开">
                            <el-icon :size="20">
                                <Folder />
                            </el-icon>
                        </el-link>
                        <el-link type="success" :underline="false" @click.stop="openInVsCode(res.path)"
                            title="VSCode中打开">
                            <el-icon :size="20">
                                <VideoPlay />
                            </el-icon>
                        </el-link>
                    </div>
                </div>
            </el-scrollbar>
        </div>
    </section>
</template>

<script setup lang="ts">
import { Search } from '@element-plus/icons-vue'
import { invoke } from '@tauri-apps/api/core'
import { Folder, VideoPlay } from '@element-plus/icons-vue'
import { openInFinder, openInVsCode } from '@/composables/useHome'
import database from '@/api/database'
import { listen } from '@tauri-apps/api/event'

const search = ref('')
const searchRef = useTemplateRef('search-input')
const searchResult = ref<Project[]>([])
const baseHeight = ref(80)
const resultRef = useTemplateRef('result-ref')
const focusIndex = ref<number | undefined>()

const init = () => {
    search.value = ''
    searchResult.value = []
    focusIndex.value = undefined
    invoke("set_window_height", { height: baseHeight.value })
    resultRef.value?.setScrollTop(0)
}
const searchChange = async () => {
    if (!search.value) {
        searchResult.value = []
        invoke("set_window_height", { height: baseHeight.value })
        return
    }
    (await database()).table('projects')
        .whereOr('name', 'like', '%' + search.value + '%')
        .whereOr('path', 'like', '%' + search.value + '%')
        .whereOr('description', 'like', '%' + search.value + '%').get<Project>().then((res) => {
            searchResult.value = res
            if (searchResult.value.length > 0) {
                invoke("set_window_height", { height: 200 })
            } else {
                invoke("set_window_height", { height: baseHeight.value })
            }
        })
}
// 回车键打开第一个结果
const enterHandle = () => {
    if (searchResult.value.length) {
        openInVsCode(searchResult.value[(focusIndex.value ?? 1) - 1].path)
    }
}
const onKeyDown = (e: KeyboardEvent) => {
    if (e.key === 'Escape') {
        if (search.value) {
            init()
        } else {
            invoke('hidden_window')
        }
    }
    if (e.key === "ArrowUp" && searchResult.value.length) {
        e.preventDefault()
        if (focusIndex.value && focusIndex.value !== 1) {
            focusIndex.value = Math.abs((focusIndex.value - 1) % searchResult.value.length)
        } else {
            focusIndex.value = searchResult.value.length
        }
        resultRef.value?.$el.querySelectorAll('.item')[focusIndex.value - 1].scrollIntoView({ block: 'center', behavior: 'smooth' })
    }
    if (e.key === "ArrowDown" && searchResult.value.length) {
        e.preventDefault()
        if (focusIndex.value !== undefined) {
            focusIndex.value = Math.max((focusIndex.value + 1) % (searchResult.value.length + 1), 1)
        } else {
            focusIndex.value = 1
        }
        resultRef.value?.$el.querySelectorAll('.item')[focusIndex.value - 1].scrollIntoView({ block: 'center', behavior: 'smooth' })
    }
}
onBeforeMount(() => {
    listen("search-hidden", ({ payload }: {
        payload: boolean
    }) => {
        init()
        if (!payload) {
            searchRef.value?.focus()
        } else {
        }
    })
})
onMounted(() => {
    window.addEventListener('keydown', onKeyDown)
})
</script>

<style lang="scss" scoped>
section {
    width: 100vw;
    height: 100vh;
    overflow: hidden;

    .form {
        padding: 3px;
        // border-bottom: 1px solid #ebeef5;
    }

    .result {
        margin-top: 5px;
        overflow: hidden;

        .item {
            display: flex;
            gap: 5px;
            padding: 0 20px;
            height: 35px;
            align-items: center;
            transition: all 0.3s;
            cursor: default;

            &:nth-child(odd) {
                background-color: var(--el-table-tr-bg-color);
            }

            &:nth-child(even) {
                background-color: var(--el-fill-color-lighter);
            }

            &.active {
                background-color: var(--el-color-primary-light-7);
            }

            .name,
            .path,
            .description,
            .operate {
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }

            .name {
                flex: 0 0 180px;
            }

            .path {
                flex: 0 0 200px;
                font-size: 12px;
                color: var(--el-color-info-light-3);
            }

            .description {
                font-size: 12px;
                flex: 0 0 190px;
                color: var(--el-color-info-light-3);
            }

            .operate {
                flex: 0 0 55px;
            }
        }
    }
}
</style>